#ifndef CQ_OBJECT_H
#define CQ_OBJECT_H

#include "CQ_defines.h"
#include "CQ_looper.h"
#include "CQ_guard.h"
#include "CQ_thread.h"

#include <algorithm>

DEFINE_NAMESPACE_CQ_BEGIN

class CQObject
{
public:
	CQObject(CQObject* parent = nullptr)
		: m_looper(CQLooper::currentLooper())
		, m_parent(parent)
	{
		if (m_parent) {
			m_parent->addChild(this);
		}
	}

	virtual ~CQObject()
	{
		if (m_parent) {
			m_parent->removeAchild(this);
			m_parent = nullptr;
		}
		clearChildren();
	}

	CQLooper* eventLooper()
	{
		return m_looper;
	}

	void moveToThread(CQThread* th_)
	{
		m_looper = CQLooper::getLooper(th_->getId());
	}

	CQGuard guard()
	{
		return m_guard;
	}

	int exec()
	{
		return m_looper->exec();
	}

protected:
	void addChild(CQObject* aChild)
	{
		auto ite = std::find(m_children.begin(), m_children.end(), aChild);
		if (ite == m_children.end()) {
			m_children.push_back(aChild);
		}
	}

	void removeAchild(CQObject* aChild)
	{
		auto ite = std::find(m_children.begin(), m_children.end(), aChild);
		if (ite != m_children.end()) {
			(*ite)->m_parent = nullptr;
			m_children.erase(ite);
		}
	}

	void clearChildren()
	{
		std::for_each(m_children.begin(), m_children.end(), [](CQObject* a_) { a_->m_parent = nullptr; delete a_; });
	}

	CQLooper* m_looper;
	CQObject* m_parent;
	std::list<CQObject*> m_children;
	CQGuard m_guard;
};

DEFINE_NAMESPACE_CQ_END

#endif // CQ_OBJECT_H
